package com.tanhua.system.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.dubbo.server.pojo.Publish;


import com.tanhua.system.enums.AgeRangeEnum;
import com.tanhua.system.enums.AreaEnum;
import com.tanhua.system.enums.DutyRangeEnum;
import com.tanhua.system.enums.SexEnum;
import com.tanhua.system.mapper.LoggingMapper;
import com.tanhua.system.mapper.UserInfoMapper;
import com.tanhua.system.mapper.UserMapper;
import com.tanhua.system.pojo.Logging;
import com.tanhua.system.pojo.User;
import com.tanhua.system.pojo.UserInfo;
import com.tanhua.system.vo.DashBoardYear;
import com.tanhua.system.vo.DashboardDistribution;
import com.tanhua.system.vo.DashboardResult;
import com.tanhua.system.vo.Tasks;
import org.apache.commons.lang3.RandomUtils;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;


import java.util.*;


/**
 * @Author: Mr.blue
 * @Description:
 * @Date: Created in 11:20 2021/1/17
 * @ModifiedBy:
 */
@Service
public class DashboardService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoggingMapper loggingMapper;


    /**
     * 查询后台概要信息
     * @return 后台必要数据
     */
    public DashboardResult queryDashboard() {
        //创建返回对象
        DashboardResult dashboardResult = new DashboardResult();

        //当前时间(毫秒值)
        long current = DateUtil.current();
        //今天0时(毫秒值)
        Date theDay = DateUtil.beginOfDay(new Date(current));
        //昨天0时(毫秒值)
        Date yesterday = new Date(DateUtil.offsetDay(theDay, -1).getTime());
        //前一个星期(毫秒值)
        Date theLastWeek = DateUtil.beginOfWeek(DateUtil.date());
        //前一个月(毫秒值)
        Date theLastMonth = DateUtil.beginOfMonth(DateUtil.date());

        //昨日新增
//        QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
//        queryWrapper1.le("created",theDay).ge("created",yesterday);
//        queryWrapper1.between("created",theDay,yesterday);
//        Integer newUsersYesterday = this.userInfoMapper.selectCount(queryWrapper1);
//+        Integer newUsersYesterday =

//        //1★★★ newUsersToday 今日的新增
//        QueryWrapper<UserInfo> queryWrapper2 = new QueryWrapper<>();
////        queryWrapper1.le("created",current).ge("created",theDay);
//        queryWrapper1.between("created",current,theDay);
//        Integer newUsersToday = this.userInfoMapper.selectCount(queryWrapper2);

//        DashboardService.getResultMaxMinLimit(newUsersToday);

        //2★★★ newUsersTodayRate 新增用户增长率
//        Integer newUsersTodayRate;

 /*       if (newUsersYesterday != 0) {
            newUsersTodayRate = newUsersToday / newUsersYesterday;
        } else {
            newUsersTodayRate = null;
        }*/

//
//        //昨日登录次数
//        QueryWrapper<Logging> queryWrapper3 = new QueryWrapper<>();
////        queryWrapper3.le("login",theDay)
////                     .ge("login",yesterday);
//        queryWrapper3.between("login",theDay,yesterday);
//        Integer loginTimesYesterday = this.loggingMapper.selectCount(queryWrapper3);
//        DashboardService.getResultMaxMinLimit(loginTimesYesterday);


        //3★★★ loginTimesToday 今日登录次数
//        QueryWrapper<Logging> queryWrapper4 = new QueryWrapper<>();
//        queryWrapper4.le("login",current)
//                     .ge("login",theDay);
//        queryWrapper4.between("login",current,theDay);

        Integer newUsersToday = RandomUtils.nextInt(50,100);
        Integer newUsersYesterday = RandomUtils.nextInt(60,90);

        Integer newUsersTodayRate;

        if(newUsersYesterday!= 0){
            newUsersTodayRate = (newUsersToday - newUsersYesterday) * 100 / newUsersYesterday;
        }else{
            newUsersTodayRate = null;
        }



        Integer loginTimesToday = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).toDate())
                        .ge(Logging::getLogin, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).toDate())
        );
        DashboardService.getResultMaxMinLimit(loginTimesToday);




        Integer loginTimesYesterday = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).minusDays(1).toDate())
                        .ge(Logging::getLogin, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusDays(1).toDate())
        );


        //4★★★ loginTimesTodayRate 今日登录次数涨跌率

        Integer loginTimesTodayRate;

        if(loginTimesYesterday != 0){
             loginTimesTodayRate = (loginTimesToday - loginTimesYesterday) * 100 / loginTimesYesterday;
        }else{
            loginTimesTodayRate = null;
        }


        //昨日活跃用户
//        QueryWrapper<Logging> queryWrapper5 = new QueryWrapper<>();
////        queryWrapper5.le("login",theDay)
////                .ge("login",yesterday)
//        queryWrapper5.between("login",theDay,yesterday);
////                .select("distinct,user_id");
//        Integer activeUsersYesterday = this.loggingMapper.selectCount(queryWrapper5);
        Integer activeUsersYesterday = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).minusDays(1).toDate())
                        .ge(Logging::getLogout, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusDays(1).toDate())
        );



        //5.★★★ activeUsersToDay 今日活跃用户
//        QueryWrapper<Logging> queryWrapper6 = new QueryWrapper<>();
//        queryWrapper6.le("login",current)
//                .ge("login",theDay)
 //       queryWrapper6.between("login",current,theDay);
//                .select("distinct,user_id");
        Integer activeUsersToday = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).toDate())
                        .ge(Logging::getLogout, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).toDate())
        );
        DashboardService.getResultMaxMinLimit(activeUsersToday);


        //6.★★★ activeUsersTodayRate 今日活跃用户涨跌率


        Integer activeUsersTodayRate;
        if(activeUsersYesterday != 0){
            activeUsersTodayRate = (activeUsersToday - activeUsersYesterday)*100/activeUsersToday;
        }else{
            activeUsersTodayRate = null;
        }




        //前日活跃用户
        Integer activeUsersTheDayBeforeYesterday = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).minusDays(2).toDate())
                        .ge(Logging::getLogout, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusDays(2).toDate())
        );

        Integer activeUsersYesterdayRate = (activeUsersYesterday-activeUsersTheDayBeforeYesterday)*100/activeUsersTheDayBeforeYesterday;

        //7.★★★ cumulativeUsers 累计用户
        //去mysql里面查询数据,累计用户的数量_ok
//        QueryWrapper<User> queryWrapper7 = new QueryWrapper<>();
//        queryWrapper7.isNull("id");
        Integer cumulativeUsers = loggingMapper.selectCount(
                null
        );
        DashboardService.getResultMaxMinLimit(cumulativeUsers);


//        //8.★★★ activePassMonth 过去30天内的活跃用户
//        //去mongoDB里面去查publish的创建Id
//        //循环遍历每个userId,在每个userId里面进行判断
//        //如果该userId满足条件(null)
//        Query query = Query.query(Criteria.where("user_id")
//                                            .is("userId").and("login")
//                                            .in(theLastMonth,current));
//
//        int activePassMonth = (int)this.mongoTemplate.count(query, Publish.class);
//        DashboardService.getResultMaxMinLimit(activePassMonth);
        int activePassMonth = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).toDate())
                        .ge(Logging::getLogout, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusMonths(1).toDate())
        );

//        //9.★★★ activePassWeek 过去7天内的活跃用户
//        //去mongoDB里面去查publish的创建Id
//        //循环遍历每个userId,在每个userId里面进行判断
//        //如果该userId满足条件(null)
//
//        Query query1 = Query.query(Criteria.where("user_id")
//                                           .is("userId").and("login")
//                                           .in(theLastWeek,current));
//
//        int activePassWeek = (int)this.mongoTemplate.count(query1,Publish.class);
//        DashboardService.getResultMaxMinLimit(activePassWeek);
        int activePassWeek = loggingMapper.selectCount(
                new LambdaQueryWrapper<Logging>()
                        .le(Logging::getLogin, LocalDateTime.now().withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).toDate())
                        .ge(Logging::getLogout, LocalDateTime.now().withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusDays(7).toDate()));


        //封装数据
        dashboardResult.setCumulativeUsers(cumulativeUsers);
        dashboardResult.setActivePassMonth(activePassMonth);
        dashboardResult.setActivePassWeek(activePassWeek);
        dashboardResult.setNewUsersToday(newUsersToday);
        dashboardResult.setNewUsersTodayRate(newUsersTodayRate);
        dashboardResult.setLoginTimesToday(loginTimesToday);
        dashboardResult.setActiveUsersYesterday(activeUsersYesterday);
        dashboardResult.setActiveUsersToday(activeUsersToday);

        dashboardResult.setLoginTimesTodayRate(loginTimesTodayRate);
        dashboardResult.setActiveUsersYesterdayRate(activeUsersYesterdayRate);
        dashboardResult.setActiveUsersTodayRate(activeUsersTodayRate);


        return dashboardResult;
    }

    /**
     * 查询后台的 新增、活跃用户、次日留存率
     * @param sd 开始时间
     * @param ed 结束时间
     * @param type 101 新增 102 活跃用户 103 次日留存率
     * @return 状态信息
     */
    public Map<String, Object> users(String sd, String ed, Integer type) {
//        DashBoardYear dashBoardYear = new DashBoardYear();
//        //利用假数据.没必要创建表,直接利用Random赋值
//
//        Tasks tasksLastYear = DashboardService.getTasksData();
//        Tasks tasksThisYear = DashboardService.getTasksData();
//
//        //设置去年的值
//        dashBoardYear.setLastYear(tasksLastYear);
//        //设置今年的值
//        dashBoardYear.setThisYear(tasksThisYear);
//
//        return dashBoardYear;
        switch (type) {
            case 101: {
                // 101 新增
                break;
            }
            case 102: {
                // 102 活跃用户
                break;
            }
            case 103: {
                // 103 次日留存率
                break;
            }
        }

        Map<String, Object> result = new HashMap<>(2);

        List<Map<String, Object>> thisYear = new ArrayList<>();
        List<Map<String, Object>> lastYear = new ArrayList<>();

        for (int i = 1; i <= 12; i++) {
            Map<String, Object> temp = new HashMap<>(2);
            Map<String, Object> temp2 = new HashMap<>(2);

            temp.put("title", String.valueOf(i));
            temp.put("amount", RandomUtils.nextInt(5000, 9999));
            thisYear.add(temp);

            temp2.put("title", String.valueOf(i));
            temp2.put("amount", RandomUtils.nextInt(1000, 4999));
            lastYear.add(temp2);

        }


        result.put("thisYear", thisYear);
        result.put("lastYear", lastYear);
        return result;
    }



    public DashboardDistribution queryDashboardOtherData(String sd, String ed) {
        DashboardDistribution dashboardDistribution = new DashboardDistribution();

        //行业分布Top10
        List<Tasks> industryList = new ArrayList<>();
        for (DutyRangeEnum dutyRangeEnum : DutyRangeEnum.values()) {
            Tasks industryDistribution = new Tasks();

            industryDistribution.setTitle(dutyRangeEnum.getDesc());
            industryDistribution.setAmount(RandomUtils.nextInt(1,50));

            industryList.add(industryDistribution);
        }

        //年龄段
        List<Tasks> ageList = new ArrayList<>();
        for (AgeRangeEnum ageRangeEnum : AgeRangeEnum.values()) {
            Tasks ageDistribution = new Tasks();
            ageDistribution.setTitle(ageRangeEnum.getDesc());
            //设置数据
            ageDistribution.setAmount(RandomUtils.nextInt(50,9999));

            ageList.add(ageDistribution);
        }

        //性别
        List<Tasks> genderList = new ArrayList<>();
        for (SexEnum sexEnum : SexEnum.values()) {
            Tasks genderDistribution = new Tasks();
            genderDistribution.setTitle(sexEnum.getDesc());
            //设置数据
            genderDistribution.setAmount(RandomUtils.nextInt(50,9999));
            genderList.add(genderDistribution);
        }

        //地区省份Province
        List<Tasks> localProvinceList = new ArrayList<>();
        for (AreaEnum areaEnum : AreaEnum.values()) {
            Tasks localDistribution = new Tasks();
            localDistribution.setTitle(areaEnum.getProvince());
            //设置数据
            localDistribution.setAmount(RandomUtils.nextInt(50,9999));
            localProvinceList.add(localDistribution);
        }


        //地区名称Area
        List<Tasks> localAreaList = new ArrayList<>();
        for (AreaEnum areaEnum : AreaEnum.values()) {
            Tasks localTotal = new Tasks();
             localTotal.setTitle(areaEnum.getProvince());
             //设置数据
            localTotal.setAmount(RandomUtils.nextInt(20,99));
            localAreaList.add(localTotal);
        }


        dashboardDistribution.setIndustryDistribution(industryList);
        dashboardDistribution.setAgeDistribution(ageList);
        dashboardDistribution.setGenderDistribution(genderList);
        dashboardDistribution.setLocalDistribution(localProvinceList);
        dashboardDistribution.setLocalTotal(localAreaList);

        return dashboardDistribution;
    }

    /**
     * 给年份设值
     * Tasks 的属性
     * String title 日期
     * Integer amount 数量
     * @return
     */
    private static Tasks getTasksData(){
        Tasks tasksLastYear = new Tasks();

        //去年设值
        //设置一个arr[12]的数组,每个数组上的数据的变化
        int[] arr = new int[12];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomUtils.nextInt(50,9999);
        }

        for (int i = 0; i < arr.length; i++) {

            tasksLastYear.setTitle(i+"");
            tasksLastYear.setAmount(arr[i]);
        }
        return tasksLastYear;
    }


    /**
     * 限制范围
     * @param count 参数
     * @return
     */
    private static Integer getResultMaxMinLimit(Integer count) {
        //最大值500,最小值0
        if(count >= 500){
            count = 500;
        }else if(count <= 0){
            count = 0;
        }else{
            return count;
        }
        return count;
    }

    /**
     * 重载上面的方法,限制范围
     * @param min
     * @param max
     * @param number
     * @return
     */
    private static Integer getResultMaxMinLimit(Integer min,Integer max,Integer number) {
        if(number >= max){
            number = max;
        }else if(number <= min){
            number = min;
        }else{
            return number;
        }
        return number;
    }
}
